// ***************************************************************************************
// Copyright (c) 2023-2025 Peng Cheng Laboratory
// Copyright (c) 2023-2025 Shanghai Anlogic Infotech Co.,Ltd.
// Copyright (c) 2023-2025 Peking University
//
// iMAP-FPGA is licensed under Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of Mulan PSL v2 at:
// http://license.coscl.org.cn/MulanPSL2
//
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
//
// See the Mulan PSL v2 for more details.
// ***************************************************************************************

#pragma once
#include <vector>
#include <array>
#include <algorithm>
#include <assert.h>

iFPGA_NAMESPACE_HEADER_START

/**
 * @brief the database_npn4_aig database for the database
 *    _values[0] store the num_gates | num_pos | num_pis
 */
struct database_npn4_aig
{
public:
  explicit database_npn4_aig(uint32_t num_pis = 0)
    : _values({num_pis})
  {  }

  explicit database_npn4_aig(std::vector<uint32_t> const& values)
    : _values(values.begin(), values.end())
  {  }

  uint32_t size()      const { return _values.size(); }
  uint32_t num_gates() const { return _values[0] >> 16; }
  uint32_t num_pis()   const { return _values[0] & 0xff; }
  uint32_t num_pos()   const { return _values[0] >> 8 & 0xff;}

  template<typename Fn>
  void foreach_gate(Fn&& fn) const
  {
    assert( (_values.size() - num_pos() - 1u)%2 == 0);
    for(uint32_t i = 1u; i < _values.size()-num_pos(); i += 2)
    {
      fn(_values[i], _values[i+1]);
    }
  }

  template<typename Fn>
  void foreach_po(Fn&& fn) const
  {
    for(uint32_t i = _values.size() - num_pos() ; i < _values.size(); ++i)
    {
      fn(_values[i]);
    }
  }

private:
  std::vector<uint32_t> _values;
};

/**
 * @brief insert by the signals
 */
template<typename Ntk, typename Begin, typename End, typename Fn>
void insert_into_network(Ntk& ntk, Begin begin, End end, database_npn4_aig const& data, Fn&& fn) {
  using signal_t = typename Ntk::signal;
  
  assert( std::distance(begin, end) == data.num_pis() );

  std::vector<signal_t> vec_signal;
  vec_signal.emplace_back( ntk.get_constant(false) );
  for(auto it = begin; it != end; ++it) {
    vec_signal.emplace_back( *it );
  }

  data.foreach_gate( [&](uint32_t lit0, uint32_t lit1){
    assert(lit0 != lit1);
    uint32_t const index_0 = lit0 >> 1;
    uint32_t const index_1 = lit1 >> 1;
    /// make sure the index's order for emplace_back
    signal_t const s0 = ( lit0 % 2 ) ? ntk.create_not( vec_signal.at( index_0 ) ) : vec_signal.at( index_0 );
    signal_t const s1 = ( lit1 % 2 ) ? ntk.create_not( vec_signal.at( index_1 ) ) : vec_signal.at( index_1 );
    vec_signal.emplace_back( lit0 > lit1 ? ntk.create_xor( s0, s1 ) : ntk.create_and( s0, s1 ) );
  });

  data.foreach_po( [&](uint32_t lit){
    uint32_t const index = lit >> 1;
    fn( (lit % 2) ? ntk.create_not(vec_signal.at( index )) : vec_signal.at( index ) );
  });
}

/**
 * @brief construct the network from subgraph
 *  only for the database constructor
 */
template<typename Ntk>
void decode_data_rewriting( Ntk& ntk, database_npn4_aig const& data) {
  using signal_t = typename Ntk::signal;

  std::vector<signal_t> vec_signal(data.num_pis());
  std::generate(vec_signal.begin(), vec_signal.end(), [&](){
    return ntk.create_pi();
  });

  insert_into_network(ntk, vec_signal.begin(), vec_signal.end(), data, [&](auto const& s){
    ntk.create_po(s);
  });
}

/* complete NPN AIG subgraph database */
// 52223492 == 1100011100 | 11011110 | 00000100 => 796 | 222 | 4
static const std::vector<uint32_t> database_subgraphs_aig = { 52223492, 4, 7, 5,
  6, 11, 13, 8, 14, 9, 15, 17, 19, 3, 5, 6, 9, 7, 8, 25, 27, 23, 29,
  22, 28, 31, 33, 3, 4, 2, 6, 37, 39, 8, 40, 9, 41, 43, 45, 2, 5, 2,
  7, 4, 51, 49, 53, 8, 55, 9, 54, 57, 59, 2, 26, 25, 63, 2, 63, 5,
  67, 65, 68, 64, 69, 71, 73, 2, 4, 6, 23, 77, 79, 8, 80, 9, 81, 83,
  85, 5, 39, 8, 88, 2, 8, 6, 39, 93, 95, 89, 96, 91, 99, 4, 8, 2,
  103, 13, 104, 13, 27, 3, 109, 107, 111, 8, 76, 6, 22, 77, 117, 27,
  118, 115, 121, 7, 9, 22, 125, 6, 8, 23, 129, 76, 125, 130, 133,
  127, 135, 5, 8, 3, 139, 93, 141, 4, 141, 7, 145, 142, 146, 143,
  147, 149, 151, 5, 7, 8, 155, 9, 154, 157, 159, 2, 161, 4, 6, 161,
  165, 3, 167, 163, 169, 2, 9, 4, 173, 3, 8, 7, 176, 174, 179, 39,
  179, 5, 183, 181, 185, 4, 9, 155, 189, 2, 190, 165, 190, 3, 195,
  193, 197, 23, 77, 6, 77, 8, 203, 200, 205, 201, 204, 207, 209, 7,
  23, 77, 212, 9, 76, 23, 217, 6, 219, 215, 221, 23, 25, 77, 129,
  224, 226, 225, 227, 229, 231, 3, 9, 7, 103, 235, 236, 234, 237,
  239, 241, 23, 115, 7, 245, 8, 23, 77, 249, 6, 251, 247, 253, 23,
  125, 227, 257, 226, 256, 259, 261, 6, 200, 7, 201, 265, 267, 9,
  269, 49, 177, 7, 273, 25, 275, 7, 173, 4, 177, 278, 281, 25, 283,
  7, 77, 8, 287, 125, 289, 9, 165, 155, 293, 3, 295, 8, 164, 2, 294,
  299, 301, 297, 302, 4, 50, 5, 234, 307, 309, 129, 310, 11, 23,
  177, 315, 129, 317, 37, 49, 6, 320, 7, 321, 323, 325, 8, 326, 9,
  327, 329, 331, 9, 77, 7, 334, 23, 337, 129, 339, 9, 286, 26, 77,
  9, 23, 6, 346, 345, 349, 4, 234, 7, 139, 2, 354, 353, 357, 129,
  358, 77, 256, 129, 362, 2, 124, 4, 366, 3, 125, 4, 371, 367, 373,
  129, 374, 369, 377, 203, 249, 6, 76, 343, 383, 289, 384, 8, 325,
  9, 324, 389, 391, 8, 11, 51, 394, 51, 235, 4, 399, 397, 401, 367,
  371, 4, 405, 5, 404, 407, 409, 129, 411, 3, 6, 249, 415, 5, 176,
  4, 129, 2, 420, 419, 423, 6, 424, 7, 425, 427, 429, 5, 9, 2, 432,
  157, 435, 3, 7, 7, 439, 2, 441, 4, 443, 439, 444, 8, 445, 441,
  448, 447, 451, 9, 383, 24, 37, 325, 457, 9, 37, 11, 461, 50, 463,
  51, 462, 465, 467, 88, 439, 173, 439, 4, 473, 471, 475, 50, 139,
  139, 189, 3, 481, 479, 483, 129, 484, 155, 235, 293, 488, 292,
  489, 491, 493, 6, 321, 9, 51, 320, 499, 497, 501, 5, 172, 129,
  505, 4, 278, 506, 509, 7, 200, 24, 201, 513, 515, 7, 22, 347, 519,
  337, 521, 5, 399, 398, 420, 525, 527, 22, 286, 287, 346, 531, 533,
  3, 129, 4, 536, 2, 128, 4, 125, 541, 543, 537, 544, 539, 547, 8,
  77, 212, 551, 9, 201, 213, 555, 553, 557, 154, 370, 9, 371, 155,
  562, 561, 565, 24, 320, 26, 321, 569, 571, 8, 286, 9, 287, 575,
  577, 2, 542, 3, 543, 7, 583, 4, 543, 9, 587, 585, 589, 581, 591,
  25, 325, 125, 129, 9, 212, 8, 213, 77, 601, 598, 602, 599, 603,
  605, 607, 7, 93, 4, 235, 611, 612, 610, 613, 615, 617, 129, 618,
  5, 370, 7, 623, 8, 625, 373, 627, 3, 236, 129, 631, 77, 632, 125,
  201, 129, 637, 3, 154, 8, 641, 155, 165, 234, 645, 643, 647, 5,
  124, 3, 651, 542, 653, 543, 652, 129, 657, 655, 658, 4, 370, 5,
  367, 371, 664, 663, 667, 129, 669, 173, 641, 3, 124, 5, 674, 581,
  677, 129, 678, 9, 49, 155, 682, 154, 683, 685, 687, 248, 286, 22,
  287, 76, 249, 693, 695, 691, 696, 9, 22, 265, 701, 115, 702, 334,
  415, 157, 707, 6, 460, 4, 37, 7, 713, 8, 714, 711, 717, 2, 165, 9,
  721, 155, 722, 154, 723, 725, 727, 8, 154, 9, 155, 731, 733, 5,
  129, 2, 736, 173, 737, 739, 741, 165, 172, 157, 745, 13, 103, 51,
  188, 155, 751, 9, 50, 748, 755, 4, 24, 155, 759, 7, 138, 759, 763,
  2, 645, 9, 767, 731, 769, 8, 720, 6, 721, 9, 774, 773, 777, 4,
  778, 5, 779, 781, 783, 12, 173, 6, 172, 9, 789, 4, 791, 787, 793,
  2, 237, 4, 796, 129, 799, 631, 800, 125, 219, 7, 218, 77, 806,
  805, 809, 6, 235, 9, 813, 8, 812, 5, 817, 815, 819, 309, 821, 92,
  154, 3, 164, 93, 827, 155, 828, 825, 831, 188, 789, 279, 789, 5,
  837, 835, 839, 9, 644, 9, 39, 5, 844, 737, 845, 847, 849, 3, 138,
  25, 51, 2, 139, 5, 856, 855, 859, 853, 861, 77, 433, 7, 865, 9,
  865, 6, 869, 867, 871, 5, 439, 175, 875, 234, 293, 235, 295, 879,
  881, 188, 836, 839, 885, 27, 77, 25, 201, 889, 891, 888, 890, 893,
  895, 235, 237, 7, 234, 5, 900, 103, 903, 813, 904, 5, 536, 125,
  909, 6, 234, 9, 235, 4, 915, 7, 917, 913, 919, 8, 439, 237, 922,
  236, 923, 925, 927, 4, 172, 6, 930, 7, 852, 933, 935, 53, 682,
  157, 165, 6, 37, 8, 321, 943, 945, 129, 947, 5, 23, 6, 951, 249,
  953, 2, 154, 9, 957, 165, 958, 731, 961, 9, 323, 154, 234, 489,
  967, 160, 165, 5, 415, 9, 972, 7, 972, 8, 977, 975, 979, 8, 518,
  9, 519, 983, 985, 22, 26, 347, 989, 8, 320, 497, 993, 643, 827, 3,
  165, 2, 155, 999, 1001, 157, 1003, 3, 433, 154, 1007, 6, 1006, 9,
  1011, 155, 1013, 1009, 1015, 3, 11, 8, 1019, 27, 1018, 1021, 1023,
  8, 640, 173, 1027, 7, 235, 5, 1030, 4, 1031, 9, 1034, 1033, 1037,
  4, 537, 6, 1041, 9, 1043, 909, 1045, 6, 177, 5, 1049, 179, 1050,
  173, 179, 4, 1055, 1053, 1057, 9, 999, 5, 998, 7, 1062, 1061,
  1065, 129, 675, 581, 1068, 3, 13, 8, 1072, 5, 1074, 2, 12, 9,
  1073, 1079, 1080, 1077, 1083, 7, 857, 4, 857, 6, 1089, 9, 1090,
  1087, 1093, 324, 461, 325, 460, 1097, 1099, 93, 125, 415, 1102, 5,
  1105, 543, 1107, 5, 93, 7, 1110, 6, 1111, 2, 1114, 3, 1115, 1117,
  1119, 9, 1121, 1113, 1123, 8, 998, 2, 164, 9, 1128, 155, 1131,
  1126, 1132, 1127, 1133, 1135, 1137, 6, 335, 249, 701, 1141, 1142,
  77, 701, 7, 1147, 6, 1146, 249, 1151, 1149, 1152, 23, 579, 22,
  578, 1157, 1159, 77, 155, 93, 1163, 4, 415, 1031, 1167, 4, 1030,
  93, 1171, 1169, 1172, 9, 415, 155, 1176, 641, 1179, 287, 383, 249,
  1183, 125, 488, 124, 489, 1187, 1189, 5, 414, 2, 10, 1193, 1195,
  8, 1197, 9, 1196, 1199, 1201, 155, 172, 154, 176, 1205, 1207, 9,
  766, 730, 767, 1211, 1213, 875, 1007, 129, 1217, 455, 519, 23,
  165, 6, 173, 1223, 1225, 383, 641, 9, 1229, 643, 1231, 6, 201,
  249, 1235, 93, 415, 6, 415, 5, 1241, 1238, 1243, 8, 1242, 1239,
  1246, 1245, 1249, 155, 723, 9, 973, 53, 1254, 454, 519, 2, 293, 3,
  292, 157, 1263, 1261, 1264, 23, 1001, 9, 1268, 7, 1268, 8, 1273,
  1271, 1275, 5, 371, 37, 1279, 129, 1281, 165, 643, 49, 103, 7,
  1286, 6, 1287, 9, 1290, 1289, 1293, 7, 335, 265, 1297, 249, 1299,
  1050, 1054, 1057, 1303, 129, 200, 155, 1129, 93, 1309, 22, 124, 3,
  102, 49, 1315, 7, 1317, 25, 1319, 9, 645, 643, 1323, 9, 164, 154,
  173, 1327, 1329, 9, 640, 1284, 1333, 286, 347, 533, 1337, 27, 235,
  10, 1341, 11, 1340, 1343, 1345, 2, 759, 9, 1348, 3, 761, 1351,
  1353, 461, 714, 460, 715, 1357, 1359, 9, 537, 7, 1362, 909, 1365,
  23, 423, 596, 1368, 597, 1369, 1371, 1373, 663, 1279, 129, 1377,
  641, 733, 165, 1381, 3, 189, 7, 1385, 4, 1386, 9, 1385, 6, 1391,
  1389, 1393, 9, 79, 155, 1061, 1129, 1399, 226, 257, 1313, 1402, 8,
  22, 286, 1407, 221, 1409, 9, 1129, 155, 998, 1412, 1415, 4, 439,
  173, 1418, 439, 1049, 5, 1423, 1421, 1425, 160, 1129, 7, 37, 9,
  36, 1431, 1433, 49, 1435, 129, 1437, 5, 51, 1177, 1441, 1176,
  1440, 129, 1445, 1443, 1446, 9, 213, 212, 550, 1451, 1453, 157,
  1129, 3, 158, 1456, 1459, 3, 155, 2, 733, 1463, 1465, 39, 460,
  235, 875, 234, 874, 1471, 1473, 103, 1475, 125, 908, 124, 909,
  1479, 1481, 675, 911, 2, 189, 51, 737, 1487, 1489, 4, 124, 909,
  1493, 675, 1495, 165, 1463, 9, 1499, 731, 1501, 6, 461, 3, 460, 5,
  1507, 1430, 1509, 1505, 1511, 2, 188, 23, 1515, 7, 1517, 6, 1516,
  9, 1520, 1519, 1523, 292, 957, 5, 438, 581, 1529, 129, 1530, 79,
  519, 9, 1534, 7, 347, 77, 1538, 349, 1541, 80, 984, 226, 519, 77,
  415, 9, 1549, 155, 1551, 79, 334, 8, 644, 165, 1557, 2, 1559,
  1323, 1557, 3, 1562, 1561, 1565, 129, 373, 23, 1568, 6, 433, 3,
  1573, 8, 1575, 5, 433, 1574, 1579, 1577, 1581, 9, 13, 2, 1585, 8,
  12, 5, 1589, 3, 1591, 1587, 1593, 8, 48, 1430, 1597, 1505, 1599,
  20, 35, 47, 60, 74, 87, 101, 113, 122, 137, 152, 170, 186, 198,
  210, 223, 233, 243, 254, 263, 270, 277, 285, 290, 304, 312, 318,
  333, 340, 342, 351, 360, 364, 379, 380, 386, 392, 402, 412, 416,
  430, 436, 452, 454, 459, 468, 477, 390, 486, 494, 502, 510, 517,
  522, 529, 535, 549, 558, 567, 573, 579, 592, 595, 596, 608, 620,
  628, 634, 638, 648, 660, 670, 673, 680, 689, 699, 704, 708, 719,
  729, 735, 742, 746, 748, 753, 756, 761, 765, 771, 784, 794, 802,
  811, 822, 833, 292, 841, 842, 850, 863, 872, 876, 883, 887, 897,
  899, 906, 911, 921, 928, 937, 938, 489, 940, 948, 954, 963, 964,
  968, 970, 980, 987, 9, 991, 994, 996, 1004, 1016, 1024, 1029,
  1039, 1047, 1059, 1067, 1070, 1085, 1095, 1101, 1108, 1125, 1139,
  1144, 1154, 1161, 1164, 1174, 1181, 1184, 1190, 1203, 1209, 1215,
  1218, 1221, 1226, 1232, 1236, 1251, 1253, 521, 1256, 1258, 1266,
  1276, 1282, 1284, 1295, 1300, 1305, 1306, 1310, 1312, 1321, 1324,
  1331, 1334, 1339, 1346, 1355, 1361, 1367, 1375, 1378, 1382, 1394,
  1396, 1400, 1404, 1411, 1416, 1426, 1428, 1438, 1448, 1455, 1460,
  1466, 1468, 1476, 1483, 1484, 1490, 1496, 1503, 124, 158, 1512, 8,
  1525, 1526, 1532, 1536, 1543, 1544, 1546, 1553, 1554, 1566, 1570,
  1582, 1594, 1600 };


iFPGA_NAMESPACE_HEADER_END




